#ifndef WL_EXT_OS_H
#define WL_EXT_OS_H

/*
    this file is for os functions
    semaphore, mutex, task, timer, sleep
*/

typedef void* wl_ext_sem;
typedef void* wl_ext_mutex;
typedef void* wl_ext_task;
typedef void* wl_ext_timer;
typedef void* wl_ext_queue;

// invalid handle
#define WL_EXT_INVALID_HANDLE NULL

// wait forever, make sem and mutex wait in blocked mode
#define WL_EXT_WAIT_FOREVER -1

/**
 * 优先级，最好实现者能依据平台的具体使用，绑定对应的枚举值
 */
enum {

    EXT_TASK_PRIORITY_LOW = 0, // low than system normal
    EXT_TASK_PRIORITY_NORMAL = 1, // normal as system normal
    EXT_TASK_PRIORITY_HIGH = 2, // high than system normal
    EXT_TASK_PRIORITY_HIGHEST = 3 // highest
};

/**
 * timer callback
 * timer: timer handle
 * pArg: user data
 */
typedef void (*wl_ext_timer_callback)(wl_ext_timer timer, void *pArg);

/**
 * task callback
 * pArg: user data
 */
typedef void (*wl_ext_task_callback)(wl_ext_task task, void *pArg);

/**
 * create mutex
 * @param mutex mutex handle
 * @param name mutex name
 * @return 0 on success, -1 on fail
 */
int wl_ext_mutex_create(wl_ext_mutex* mutex, const char* name);

/**
 * lock mutex
 * @param mutex mutex handle
 * @param timeout timeout in ms, -1 for wait forever
 * @return 0 on success, -1 on timeout, other < 0 on fail
 */
int wl_ext_mutex_lock(wl_ext_mutex mutex, int timeout);

/**
 * unlock mutex
 * @param mutex mutex handle
 * @return 0 on success, -1 on fail
 */
int wl_ext_mutex_unlock(wl_ext_mutex mutex);

/**
 * destroy mutex
 * @param mutex mutex handle
 */
void wl_ext_mutex_destroy(wl_ext_mutex mutex);


/**
 * create semaphore
 * @param sem semaphore handle
 * @param name semaphore name
 * @param initValue initial value
 * @return 0 on success, -1 on fail
 */
int wl_ext_sem_create(wl_ext_sem* sem, const char* name, int initValue);

/**
 * wait semaphore
 * @param sem semaphore handle
 * @param timeout timeout in ms, -1 for wait forever
 * @return 0 on success, -1 on timeout, other < 0 on fail
 */
int wl_ext_sem_wait(wl_ext_sem sem, int timeout);

/**
 * post semaphore
 * @param sem semaphore handle
 * @return 0 on success, -1 on fail 
 */
int wl_ext_sem_post(wl_ext_sem sem);

/**
 * destroy semaphore
 * @param sem semaphore handle
 */
void wl_ext_sem_destroy(wl_ext_sem sem);


/**
 * create timer
 * @param timer timer handle
 * @param name timer name
 * @return 0 on success, -1 on fail
 */
int wl_ext_timer_create(wl_ext_timer* timer, const char* name);

/**
 * start timer
 * @param timer timer handle
 * @param repeated repeat or not
 * @param interval interval in ms
 * @param callback timer callback
 * @param pArg user data
 * @return 0 on success, -1 on fail
 */
int wl_ext_timer_start(wl_ext_timer timer, int repeated, int interval, wl_ext_timer_callback callback, void* pArg);

/**
 * stop timer
 * @param timer timer handle
 * @return 0 on success, -1 on fail 
 */
int wl_ext_timer_stop(wl_ext_timer timer);

/**
 * destroy timer
 * @param timer timer handle
 */
void wl_ext_timer_destroy(wl_ext_timer timer);

/**
 * create task
 * @param task task handle
 * @param name task name
 * @param stackSize task stack size
 * @param priority task priority, 0: low than system normal, 1: normal as system normal, 2: high than system normal
 * @param qsize task queue size
 * @param callback task callback
 * @param pArg user data
 * @return 0 on success, -1 on fail
 */
int wl_ext_task_create(wl_ext_task* task, const char* name, int stackSize, int priority, int qsize, wl_ext_task_callback callback, void* pArg);

/**
 * destroy task
 * @param task task handle
 * @return 0 on success, -1 on fail
 */
int wl_ext_task_destroy(wl_ext_task task);

/**
 * join task
 * @param task task handle
 * @return 0 on success, -1 on fail 
 */
int wl_ext_task_join(wl_ext_task task);

/**
 * create queue
 * @param pQueue queue handle
 * @param name queue name
 * @param maxCount max message count
 * @param extra user data
 * @return 0 on success, -1 on fail
 */
int wl_ext_queue_create(wl_ext_queue *pQueue, const char *name, int maxCount, void* extra);

/**
 * get message from queue
 * @param queue queue handle
 * @param pMsg message buffer
 * @return 0 on success, -1 on timeout, other < 0 on fail 
 */
int wl_ext_queue_get(wl_ext_queue queue, void* pMsg);

/**
 * put message to queue
 * @param queue queue handle
 * @param pMsg message buffer
 * @return 0 on success, -1 on fail
 * 
 */
int wl_ext_queue_put(wl_ext_queue queue, void* pMsg);

/**
 * destroy queue
 * @param queue queue handle
 * @return 0 on success, -1 on fail
 *
 */
int wl_ext_queue_destroy(wl_ext_queue queue);

/**
 * sleep
 * @param msec sleep time in ms
 * @return 0 on success, -1 on fail
 */
int wl_ext_sleep(int msec);
#endif
